/*
 * Vec3D.h
 *
 *  Created on: Jan 1, 2011
 *      Author: burek
 */

#ifndef VEC3D_H_
#define VEC3D_H_

struct Vec3D
{
    float X, Y, Z;

    inline Vec3D( void ) {}
    inline Vec3D( const float x, const float y, const float z )
    { X = x; Y = y; Z = z; }

    inline Vec3D operator = ( const Vec3D& A )
    { X = A.X; Y = A.Y; Z = A.Z; return *this; }

    inline bool operator == ( const Vec3D& A ) const
    { return X == A.X && Y == A.Y && Z == A.Z; }

    inline Vec3D operator + ( const Vec3D& A ) const
    { return Vec3D( X + A.X, Y + A.Y, Z + A.Z ); }

    inline Vec3D operator - ( const Vec3D& A ) const
    { return Vec3D( X - A.X, Y - A.Y, Z - A.Z ); }

    inline Vec3D operator + ( const float A ) const
    { return Vec3D( X + A, Y + A, Z + A ); }

    inline Vec3D operator * ( const float A ) const
    { return Vec3D( X * A, Y * A, Z * A ); }

    inline Vec3D operator / ( const float A ) const
    { return Vec3D( X / A, Y / A, Z / A ); }

    inline float Dot( const Vec3D& A ) const
    { return A.X*X + A.Y*Y + A.Z*Z; }

    inline float Length( void ) const
    { return sqrt(X * X + Y * Y + Z * Z); }

    inline Vec3D Normalize(void) const
    {
    	float len = Length();
    	return Vec3D(X / len, Y / len, Z / len);
    }

    Vec3D Jitter(float ammount) const
    {
    	Vec3D copy = *this;
    	copy.X += ((rand() / (float)RAND_MAX) - 0.5f) * ammount;
    	copy.Y += ((rand() / (float)RAND_MAX) - 0.5f) * ammount;
    	copy.Z += ((rand() / (float)RAND_MAX) - 0.5f) * ammount;
    	copy.NormalizeIP();
    	return copy;
    }

    Vec3D JitterAO(float ammount) const
        {
        	Vec3D copy = *this;
        	copy.X += ((rand() / (float)RAND_MAX) - 0.5f) * ammount;
        	copy.Y += ((rand() / (float)RAND_MAX) - 0.5f) * ammount * 0.5f;
        	copy.Z += ((rand() / (float)RAND_MAX) - 0.5f) * ammount;
        	copy.Y *= 0.5f;
        	if(copy.Y < 0.0f) copy.Y = -copy.Y;
        	copy.NormalizeIP();
        	return copy;
        }

    inline void NormalizeIP(void)
	{
		float len = Length();
		X = X / len; Y = Y / len; Z = Z / len;
	}

    inline void operator += ( const Vec3D& A )
    { X += A.X; Y += A.Y; Z += A.Z; }

    inline void operator -= ( const Vec3D& A )
    { X -= A.X; Y -= A.Y; Z -= A.Z; }

    inline void operator *= ( const float A )
    { X *= A; Y *= A; Z *= A; }
};

#endif /* VEC3D_H_ */
